templates.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import { useParams } from 'common'
  2. import { CodeIcon } from 'lucide-react'
  3. import { useState } from 'react'
  4. import { Button, cn, Popover, PopoverContent, PopoverTrigger } from 'ui'
  5. import { TEMPLATES } from '@/components/interfaces/Settings/Logs/Logs.constants'
  6. import type { LogTemplate } from '@/components/interfaces/Settings/Logs/Logs.types'
  7. import DefaultLayout from '@/components/layouts/DefaultLayout'
  8. import LogsLayout from '@/components/layouts/LogsLayout/LogsLayout'
  9. import CardButton from '@/components/ui/CardButton'
  10. import LogsExplorerHeader from '@/components/ui/Logs/LogsExplorerHeader'
  11. import { UnknownInterface } from '@/components/ui/UnknownInterface'
  12. import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
  13. import type { NextPageWithLayout } from '@/types'
  14. export const LogsTemplatesPage: NextPageWithLayout = () => {
  15. const { ref: projectRef } = useParams()
  16. const { logsTemplates: isTemplatesEnabled, logsShowMetadataIpTemplate: showMetadataIpTemplate } =
  17. useIsFeatureEnabled(['logs:templates', 'logs:show_metadata_ip_template'])
  18. if (!isTemplatesEnabled) {
  19. return <UnknownInterface urlBack={`/project/${projectRef}/logs/explorer`} />
  20. }
  21. const allTemplates = showMetadataIpTemplate
  22. ? TEMPLATES
  23. : TEMPLATES.filter((template) => template.label !== 'Metadata IP')
  24. return (
  25. <div className="mx-auto h-full w-full px-5 py-6">
  26. <LogsExplorerHeader subtitle="Templates" />
  27. <div className="grid lg:grid-cols-3 gap-6 mt-4 pb-24">
  28. {allTemplates
  29. .sort((a, b) => a.label!.localeCompare(b.label!))
  30. .filter((template) => template.mode === 'custom')
  31. .map((template, i) => {
  32. return <Template key={i} projectRef={projectRef} template={template} />
  33. })}
  34. </div>
  35. </div>
  36. )
  37. }
  38. LogsTemplatesPage.getLayout = (page) => (
  39. <DefaultLayout>
  40. <LogsLayout title="Templates">{page}</LogsLayout>
  41. </DefaultLayout>
  42. )
  43. export default LogsTemplatesPage
  44. const Template = ({ projectRef, template }: { projectRef?: string; template: LogTemplate }) => {
  45. const [showPreview, setShowPreview] = useState(false)
  46. return (
  47. <CardButton
  48. title={template.label}
  49. icon={
  50. <div
  51. className={cn(
  52. 'duration-400 flex h-6 w-6 items-center justify-center rounded-sm transition-colors',
  53. 'border bg-background-200',
  54. 'group-hover:bg-brand-300 group-hover:text-brand-600 group-hover:border-brand-500',
  55. 'dark:border-background-selection dark:bg-background-200 dark:text-foreground',
  56. 'dark:group-hover:border-brand-600 dark:group-hover:bg-brand-300 dark:group-hover:text-brand-600'
  57. )}
  58. >
  59. <div className="scale-100 group-hover:scale-110">
  60. <CodeIcon size={12} strokeWidth={2} />
  61. </div>
  62. </div>
  63. }
  64. className="h-44"
  65. linkHref={`/project/${projectRef}/logs/explorer?q=${encodeURI(template.searchString)}`}
  66. description={template.description}
  67. footer={
  68. <div className="flex flex-row justify-end">
  69. <Popover onOpenChange={setShowPreview} open={showPreview}>
  70. <PopoverTrigger asChild>
  71. <Button
  72. asChild
  73. type="default"
  74. onClick={(e) => {
  75. e.preventDefault()
  76. setShowPreview(!showPreview)
  77. }}
  78. >
  79. <span>Preview</span>
  80. </Button>
  81. </PopoverTrigger>
  82. <PopoverContent className="rounded-lg bg-alternative p-0">
  83. <pre className="whitespace-pre-line wrap-break-word rounded-lg bg-alternative p-4 text-sm">
  84. {template.searchString}
  85. </pre>
  86. </PopoverContent>
  87. </Popover>
  88. </div>
  89. }
  90. />
  91. )
  92. }